﻿using H.Daos.Attributes;
using System;
using System.Linq;
using System.Reflection;

namespace H.Daos
{
    /// <summary>
    /// 实体基类
    /// </summary>
    [Serializable]
    public abstract class AbstractEntity : ICloneable
    {
        /// <summary>
        /// 图片的ID,用于被其他地方引用
        /// </summary>
        [Column("id", PrimaryKey = true, AutoIncrement = true)]
        public int? ID { get; set; }

        /// <summary>
        /// 空参数
        /// </summary>
        private static readonly object[] EmptyParam = new object[0];

        /// <summary>
        /// 实体复制器(子类请建议使用EntityCloner.Clone()的方式来克隆实体,避免手动使用复制语句)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        protected static class EntityCloner<T> where T : AbstractEntity
        {
            /// <summary>
            /// 缓存所有的属性,以便快速复制
            /// </summary>
            private static readonly PropertyInfo[] _Properties = (from p in typeof(T).GetProperties() where p.GetCustomAttributes(typeof(ColumnAttribute), true).Length > 0 select p).ToArray();

            /// <summary>
            /// 执行克隆
            /// </summary>
            /// <param name="src"></param>
            /// <returns></returns>
            public static T Clone(T src)
            {
                T ret = Activator.CreateInstance<T>();
                foreach (PropertyInfo p in _Properties)
                {
                    p.SetValue(ret, p.GetValue(src, EmptyParam), EmptyParam);
                }
                return ret;
            }
        }

        /// <summary>
        /// 克隆一个模型(只克隆Column字段)
        /// </summary>
        /// <returns></returns>
        public abstract object Clone();
    }
}
